import errorCodesBuilder from '../../../helpers/errorCodesBuilder';

const errorCodes = errorCodesBuilder();

export function decreaseCharge({ record, key, value, actions = {} }) {
	const ret = { ...actions };

	if (!ret[`balance.${key}.used`]) {
		ret[`balance.${key}.used`] = 0;
	}

	ret[`balance.${key}.used`] += value;

	return ret;
}

export default async function calcBalance({ uid, ops }) {
	const {
		log,
		app: {
			model: { Balance },
		},
	} = this;
	let record;
	try {
		record = await Balance.findOne({ uid });
	} catch (err) {
		const error = errorCodes['[0F][余额更新]查询余额Mongo记录失败'].from(err);
		log.error({ error, uid, ops }, error.rawMessage);
		throw error;
	}

	if (!record) {
		const error = errorCodes['[0F][余额更新]没有查询到对于余额Mongo记录'];
		log.error({ error, uid, ops }, error.rawMessage);
		throw error;
	}

	if (!record.planId) {
		const error = errorCodes['[0F][余额更新]未购买套餐'];
		log.error({ error, uid }, error.rawMessage);
		throw error;
	}

	if (record.planExpireTime < Date.now()) {
		const error = errorCodes['[0F][余额更新]套餐已过期'];
		log.error({ error, uid }, error.rawMessage);
		throw error;
	}

	let actions;
	try {
		actions = ops.reduce(
			(obj, { key, value }) =>
				decreaseCharge({ key, record, actions: obj, value: value * -1 }),
			{}
		);
		log.debug({ actions }, '余额更新');
		await Balance.updateOne({ uid }, { $inc: actions });
	} catch (err) {
		const error = errorCodes['[0F][余额更新]更新Mongo记录失败'].from(err);
		log.error({ error, ops, actions }, error.message);
		throw error;
	}

	return record;
}
